package cn.edu.dlmu.cogo.framework.web;

import cn.edu.dlmu.cogo.framework.annotation.Controller;
import cn.edu.dlmu.cogo.framework.annotation.Priority;
import cn.edu.dlmu.cogo.framework.annotation.RequestMapping;
import cn.edu.dlmu.cogo.framework.config.JavaConfig;
import cn.edu.dlmu.cogo.framework.config.WebConfig;
import cn.edu.dlmu.cogo.framework.context.*;
import cn.edu.dlmu.cogo.framework.utils.CogoClassUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

import java.util.Arrays;

/**
 * @author yixi
 */
@Priority(Level.MIN)
public class CogoWebServerAware implements ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        JavaConfig.setConfig(new WebConfig());
        WebConfig newWebConfig = JavaConfig.getConfig(WebConfig.class);
        newWebConfig.setRequestBody(initRequestBody());
        applicationContext.removeBean(WebConfig.class);
        applicationContext.setBean(newWebConfig);
        new WebServer().startServer();
    }

    /**
     * 初始化请求映射路径与请求方法
     */
    public RequestBody initRequestBody() {
        RequestBody requestBody = new RequestBody();
        CogoClassUtil.getClassesWithAnnotation(Controller.class).forEach(clazz -> {
            RequestMapping apiOnClass = clazz.getAnnotation(RequestMapping.class);
            Arrays.asList(ReflectUtil.getMethods(clazz, method -> method.getAnnotation(RequestMapping.class) != null)).forEach(method -> {
                if (ContextContainer.getApplicationContext().containsBean(clazz)) {
                    RequestMapping apiOnMethod = method.getAnnotation(RequestMapping.class);
                    CogoClass cogoClass = new CogoClass();
                    cogoClass.setMethod(method);
                    cogoClass.setClazz(clazz);
                    if (apiOnClass == null){
                        String mappingOnMethod = "".equals(apiOnMethod.value()) ? "/" + method.getName() : StrUtil.addPrefixIfNot(apiOnMethod.value(),"/");
                        requestBody.setMapping(mappingOnMethod, cogoClass);
                        Console.log("{} [CogoWeb]Api设置成功[{}][{}][{}]",Environment.getSystemTime(),mappingOnMethod,clazz.getName(),method.getName());
                    }else {
                        String mappingOnClass = "".equals(apiOnClass.value()) ? "/" + clazz.getSimpleName() : StrUtil.addPrefixIfNot(apiOnClass.value(),"/");
                        String mappingOnMethod = "".equals(apiOnMethod.value()) ? "/" + method.getName() : StrUtil.addPrefixIfNot(apiOnMethod.value(), "/");
                        requestBody.setMapping(mappingOnClass + mappingOnMethod, cogoClass);
                        Console.log("{} [CogoWeb]Api设置成功[{}][{}][{}]",Environment.getSystemTime(),mappingOnClass + mappingOnMethod,clazz.getName(),method.getName());
                    }
                }
            });
        });
        return requestBody;
    }
}
